package com.jhws.business.local.service;

import com.jhws.business.comm.bo.TblCommDimBo;
import com.jhws.business.comm.service.ITblCommDimService;
import com.jhws.business.device.service.LogDevUnlockService;
import com.jhws.business.face.bo.FaceInfo;
import com.jhws.business.local.i.INotLanCallback;
import com.jhws.business.visitor.service.ITblVisitorDimService;
import com.jhws.common.PropertiesReader;
import com.jhws.util.LogHelper;
import com.jhws.util.file.FileUtil;
import org.apache.commons.io.FilenameUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

@SuppressWarnings("Duplicates")
@Service
public class LocalService {
    @Autowired
    private ServletContext servletContext;
    @Autowired
    private HttpServletRequest request; //这里可以获取到request
    @Resource
    private ITblCommDimService commDimService;
    @Resource
    private LogDevUnlockService logDevUnlockService;
    @Resource
    private CommSynchService commSynchService;
    @Resource
    private ITblVisitorDimService visitorDimService;
    @Resource
    private CardSynchService cardSynchService;
    @Resource
    private CardPermsSynchService cardPermsSynchService;
    @Resource
    private FaceSynchService faceSynchService;
    @Resource
    private OwnerSynchService ownerSynchService;
    @Resource
    private SipAcountSynchService sipAcountSynchService;
    @Resource
    private SipAcountBindingService sipAcountBindingService;
    private boolean isWin = false;
    private boolean isLanMode = false;
    private String localIp;
    private TblCommDimBo commDimBo = null;
    private ScheduledExecutorService scheduler;
    private String localServerUrl;

    //人脸文件夹
    private final String FILE_FACE = "file/face";
    //图片广告文件夹
    private final String FILE_ADV_IMAGE = "file/advimage";
    //视频广告文件夹
    private final String FILE_ADV_VIDEO = "file/advvideo";
    //呼叫照片文件夹
    private final String FILE_CALL_IMAGE = "file/callimage";
    //开锁照片文件夹
    private final String FILE_UNLOCK_IMAGE = "file/unlockimage";

    @PostConstruct
    void init() throws Exception {
        isLanMode = PropertiesReader.getProperty("isLanMode").equals("true");
        localIp = PropertiesReader.getProperty("localIp");
        /* 局域网服务端才启动 */
        if (!isLanMode)
            return;
        localIp = PropertiesReader.getProperty("localIp");
        localServerUrl = PropertiesReader.getProperty("localServerUrl");
        String os = System.getProperty("os.name");
        if (os.toLowerCase().startsWith("win")) {
            isWin = true;
        }
        //线程池
        scheduler = Executors.newScheduledThreadPool(1);
        //获取局域网小区
        commDimBo = getLocalSrvComm();
        //创建人脸文件夹
        String path = getPath(FILE_FACE);
        File file = new File(path);
        if (!file.exists()) {
            file.mkdirs();
        }
        //门口机图片广告文件夹
        path = getPath(FILE_ADV_IMAGE);
        file = new File(path);
        if (!file.exists()) {
            file.mkdirs();
        }
        //门口机视频广告文件夹
        path = getPath(FILE_ADV_VIDEO);
        file = new File(path);
        if (!file.exists()) {
            file.mkdirs();
        }
        //呼叫照片文件夹
        path = getPath(FILE_CALL_IMAGE);
        file = new File(path);
        if (!file.exists()) {
            file.mkdirs();
        }
        //开锁照片文件夹
        path = getPath(FILE_UNLOCK_IMAGE);
        file = new File(path);
        if (!file.exists()) {
            file.mkdirs();
        }
        synch(30);
    }

    public boolean isLanMode() {
        return isLanMode;
    }

    private String getPath(String filePath) {
        if (isWin) {
            return servletContext.getRealPath(filePath);
        } else {
            return "/root/packages/" + filePath;
        }
    }

    public String saveCallImage(MultipartFile file, String fileName) throws IOException {
        if (isLanMode) {
            File targetFile = new File(getPath(FILE_CALL_IMAGE), fileName);
            // 保存
            file.transferTo(targetFile);
            return FILE_CALL_IMAGE + "/" + fileName;
        }
        return null;
    }

    public String saveUnlockImage(MultipartFile file, String fileName) throws IOException {
        if (isLanMode) {
            File targetFile = new File(getPath(FILE_UNLOCK_IMAGE), fileName);
            // 保存
            file.transferTo(targetFile);
            return FILE_UNLOCK_IMAGE + "/" + fileName;
        }
        return null;
    }

    public String saveAdvImage(MultipartFile file, String fileName, INotLanCallback notLanCallback) throws IOException {
        if (isLanMode) {
            fileName = fileName + "." + FilenameUtils.getExtension(file.getOriginalFilename());
            File targetFile = new File(getPath(FILE_ADV_IMAGE), fileName);
            // 保存
            file.transferTo(targetFile);
            return FILE_ADV_IMAGE + "/" + fileName;
        } else {
            return notLanCallback.callback();
        }
    }

    public FaceInfo saveFaceImage(MultipartFile image, MultipartFile face, FaceInfo faceInfo) throws IOException {
        if (isLanMode) {
            String imageName = faceInfo.getOwnerCode() + ".jpg";
            File targetFile = new File(getPath(FILE_FACE), imageName);
            // 保存照片
            image.transferTo(targetFile);
            String imageUrl = FILE_FACE + "/" + imageName;
            faceInfo.setImageUrl(imageUrl);
            String faceName = faceInfo.getOwnerCode() + ".data";
            targetFile = new File(getPath(FILE_FACE), faceName);
            // 保存特征码
            face.transferTo(targetFile);
            String faceUrl = FILE_FACE + "/" + faceName;
            faceInfo.setFaceFeature(faceUrl);
        }
        return faceInfo;
    }

    public String getUrl(String path) {
        return request.getScheme() + "://" + localIp + ":" + request.getServerPort() + request.getContextPath() + "/" + path;
    }

    public File getFile(String path) {
        String localPath = getPath(path);
        return new File(localPath);
    }

    //同步业主
    private void ownerSynch() throws Exception {
        if (!isLanMode) {
            return;
        }
        ownerSynchService.mergeOwner(localServerUrl, commDimBo.getCommCode(), getLocalSrvHeaders());
    }

    //同步sip帐号
    private void sipAcountSynch() throws Exception {
        if (!isLanMode) {
            return;
        }
        sipAcountSynchService.mergeSipAcount(localServerUrl, getLocalSrvHeaders());
    }

    //同步sip帐号绑定关系
    private void sipAcountBinding() throws Exception {
        if (!isLanMode) {
            return;
        }
        sipAcountBindingService.mergeSipAcount(localServerUrl, commDimBo.getCommCode(), getLocalSrvHeaders());
    }

    //同步IC卡
    private void cardSynch() throws Exception {
        if (isLanMode) {
            cardSynchService.mergeCard(localServerUrl, commDimBo.getCommCode(), getLocalSrvHeaders());
        }
    }

    //同步IC权限
    private void cardPerms() throws Exception {
        if (isLanMode) {
            cardPermsSynchService.mergeCardPerms(localServerUrl, commDimBo.getCommCode(), getLocalSrvHeaders());
        }
    }

    //同步IC权限
    private void faceSynch() throws Exception {
        if (isLanMode) {
            faceSynchService.mergeFace(localServerUrl, commDimBo.getCommCode(), getLocalSrvHeaders());
        }
    }

    /* 获取局域网服务器的小区号，前提是局域网服务端只能存在唯一的小区，记得清空其他数据 */
    private TblCommDimBo getLocalSrvComm() throws Exception {
        List<TblCommDimBo> list = commDimService.findTblCommDimByWhere("");
        if (list.size() == 0)
            return null;
        else
            return list.get(0);
    }

    //小区密码
    private Map<String, String> getLocalSrvHeaders() throws Exception {
        if (commDimBo == null)
            return null;
        Map<String, String> map = new HashMap<>();
        map.put("commCode", commDimBo.getCommCode());
        map.put("commPassword", commDimBo.getCommPassword());
        return map;
    }

    public void synchOwner() {
        scheduler.execute(() -> {
            try {
                ownerSynch();
            } catch (Exception e) {
                e.printStackTrace();
                LogHelper.e("error: " + e.toString());
            }
            try {
                sipAcountSynch();
            } catch (Exception e) {
                e.printStackTrace();
                LogHelper.e("error: " + e.toString());
            }
            try {
                sipAcountBinding();
            } catch (Exception e) {
                e.printStackTrace();
                LogHelper.e("error: " + e.toString());
            }
        });
    }

    private void synch(long delay) {
        scheduler.schedule(() -> {
            try {
                commSynchService.mergeComm(localServerUrl, commDimBo.getCommCode(), getLocalSrvHeaders());
            } catch (Exception e) {
                e.printStackTrace();
                LogHelper.e("error: " + e.toString());
            }
            try {
                ownerSynch();
            } catch (Exception e) {
                e.printStackTrace();
                LogHelper.e("error: " + e.toString());
            }
            try {
                sipAcountSynch();
            } catch (Exception e) {
                e.printStackTrace();
                LogHelper.e("error: " + e.toString());
            }
            try {
                sipAcountBinding();
            } catch (Exception e) {
                e.printStackTrace();
                LogHelper.e("error: " + e.toString());
            }
            try {
                cardSynch();
            } catch (Exception e) {
                e.printStackTrace();
                LogHelper.e("error: " + e.toString());
            }
            try {
                cardPerms();
            } catch (Exception e) {
                e.printStackTrace();
                LogHelper.e("error: " + e.toString());
            }
            try {
                faceSynch();
            } catch (Exception e) {
                e.printStackTrace();
                LogHelper.e("error: " + e.toString());
            }
            try {
                //删除3个月以前的开锁文件
                String path = getPath(FILE_UNLOCK_IMAGE);
                FileUtil.deleteFileTime(path, path, FileUtil.MONTHS_3);
                logDevUnlockService.delete3Month();
            } catch (Exception e) {
                e.printStackTrace();
                LogHelper.e("error: " + e.toString());
            }
            try {
                //删除3个月以前的呼叫文件
                String path = getPath(FILE_CALL_IMAGE);
                FileUtil.deleteFileTime(path, path, FileUtil.MONTHS_3);
                visitorDimService.delete3Month();
            } catch (Exception e) {
                e.printStackTrace();
                LogHelper.e("error: " + e.toString());
            }
        }, delay, TimeUnit.SECONDS);
    }

    /**
     * @Comment: spring task, 自动运行，由app.properties文件中的isLanMode属性控制是否执行
     * @Param:
     */
    @Scheduled(cron = "0 0 1 * * *")
    void updateLocalServerDataTask() {
        /* 局域网服务端才启动 */
        if (!isLanMode)
            return;
        int executeUpdateLocalServerInSeconds = 7200;
        int delay = (int) (Math.random() * executeUpdateLocalServerInSeconds);
        synch(delay);
    }

}


